<template>
  <view :ref="editorRef" :class="[ns.b(), readonly ? ns.m('readonly') : '', disabled ? ns.m('disabled') : '']">
    <template v-if="!!c.codeList && items.length > 0">
      <i-biz-code-list
        :class="[ns.e('code-list'), ns.is('reverse-color', !!c.editorParams?.REVERSECOLOR)]"
        :value="text"
        :codeListItems="items"
        :codeList="c.codeList"
        :showMode="c.editorParams?.SHOWMODE"
      ></i-biz-code-list>
    </template>
    <template v-else>
      {{ text }}
    </template>
  </view>
</template>
<script lang="ts">
export default {
  options: {
    addGlobalClass: true,
    virtualHost: true,
    styleIsolation: "shared"
  }
}
</script>
<script setup lang="ts">
  import { Ref, ref, watch } from "vue";
  import { getSpanProps, getEditorEmits } from "@/props";
  import { useNamespace, useFocusAndBlur } from "@/use";
  import { SpanEditorController } from "./i-biz-span.controller";
  import { isNil } from "ramda";
  import dayjs from "dayjs";
  import { DataTypes } from "@ibiz-template/core";
  import { CodeListItem } from "@ibiz-template/runtime";

  const props = defineProps(getSpanProps<SpanEditorController>());
  const emit = defineEmits(getEditorEmits());
  const c = props.controller;
  const ns = useNamespace("span");
  const text: Ref<string> = ref("");
  const codeList = c.codeList;
  const textSeparator = c.model.textSeparator || c.editorParams?.TEXTSEPARATOR || ",";

  const isValidDateFormat = (dateStr: string, format: string): boolean => {
    if (dateStr === format) {
      return false;
    }
    return dayjs(dateStr, format, true).isValid();
  };

  watch(
    () => props.value,
    (newVal, oldVal) => {
      if (newVal !== oldVal) {
        if (isNil(newVal)) {
          text.value = "";
          return;
        }
        const { valueFormat, dataType, unitName } = c.parent;
        if (c.model.valueType === "SIMPLES") {
          text.value = (newVal as string[]).join(textSeparator);
        } else if (c.model.valueType === "OBJECT") {
          text.value = (newVal as IData)[c.model.objectNameField ? c.model.objectNameField : "srfmajortext"];
        } else if (c.model.valueType === "OBJECTS") {
          const tempValue: string[] = [];
          (newVal as IData[]).forEach((_item: IData) => {
            tempValue.push(_item[c.model.objectNameField ? c.model.objectNameField : "srfmajortext"]);
          });
          text.value = tempValue.join(textSeparator);
        } else if (c.model.editorType === "ADDRESSPICKUP") {
          // 解析地址选择器的JSON字符串数据
          try {
            const tempValue: string[] = [];
            const items: IData[] = JSON.parse(newVal as string);
            items.forEach((_item: IData) => {
              tempValue.push(_item[c.model.objectNameField ? c.model.objectNameField : "srfmajortext"]);
            });
            text.value = tempValue.join(textSeparator);
          } catch (error) {
            ibiz.log.error(error);
          }
        } else if (valueFormat) {
          try {
            if (dataType != null && DataTypes.isDate(dataType)) {
              text.value = dayjs(newVal as string).format(valueFormat);
            } else {
              // 面板属性项是拿不到dataType的，此时先用dayjs格式化，如果能格出来说明是时间型，否则走text-format
              const tempVal = dayjs(newVal as string).format(valueFormat);
              if (isValidDateFormat(tempVal, valueFormat)) {
                text.value = tempVal;
              } else {
                text.value = ibiz.util.text.format(`${newVal}`, valueFormat);
              }
            }
          } catch (error) {
            text.value = `${newVal}`;
            ibiz.log.error(error);
          }
        } else {
          text.value = `${newVal}`;
        }
        if (unitName) {
          text.value += unitName;
        }
      }
    },
    {
      immediate: true,
    }
  );

  // 代码表数据
  const items = ref<readonly CodeListItem[]>([]);
  if (codeList) {
    watch(
      () => props.data,
      (newVal) => {
        c.loadCodeList(newVal).then((_codeList) => {
          items.value = _codeList;
        });
      },
      {
        immediate: true,
        deep: true,
      }
    );
  }

  // 聚焦失焦事件
  const { componentRef: editorRef } = useFocusAndBlur(
    () => emit("focus"),
    () => emit("blur")
  );
</script>
<style lang="scss">
  @include b("span") {
    display: block;
    width: 100%;
    font-size: getCssVar(form-item, font-size);
    line-height: getCssVar(editor, default, line-height);
    color: inherit;
    white-space: pre-line;
    @include utils-ellipsis;

    @include m(disabled) {
      color: getCssVar("form-item", "disabled-color");
    }

    @include m(readonly) {
      color: getCssVar("form-item", "readonly-color");
    }
    @include e("code-list") {
      @include when("reverse-color") {
        .#{bem("code-list","item")} {
          padding: getCssVar(spacing-extra, tight) getCssVar(spacing-base, tight);
          border-radius: getCssVar(border-radius, large);
          color: getCssVar(color, default);
          background-color: getCssVar("code-list", "item-color");
        }
      }
    }
  }
</style>
